/**
  ******************************************************************************
  * File Name          : USART.c
  * Description        : This file provides code for the configuration
  *                      of the USART instances.
  ******************************************************************************
  ** This notice applies to any and all portions of this file
  * that are not between comment pairs USER CODE BEGIN and
  * USER CODE END. Other portions of this file, whether
  * inserted by the user or by software development tools
  * are owned by their respective copyright owners.
  *
  * COPYRIGHT(c) 2018 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "usart.h"

#include "gpio.h"
#include "dma.h"

/* USER CODE BEGIN 0 */
#include "flash_if.h"
USART_RECEIVETYPE UsartType;
uint32_t p_size;
uint32_t q,w,h;
/* USER CODE END 0 */

UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;

/* USART1 init function */

void MX_USART1_UART_Init(void)
{

    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }

}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{

    GPIO_InitTypeDef GPIO_InitStruct;
    if(uartHandle->Instance==USART1)
    {
        /* USER CODE BEGIN USART1_MspInit 0 */

        /* USER CODE END USART1_MspInit 0 */
        /* USART1 clock enable */
        __HAL_RCC_USART1_CLK_ENABLE();

        /**USART1 GPIO Configuration
        PA9     ------> USART1_TX
        PA10     ------> USART1_RX
        */
        GPIO_InitStruct.Pin = GPIO_PIN_9;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        GPIO_InitStruct.Pin = GPIO_PIN_10;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        /* USART1 DMA Init */
        /* USART1_RX Init */
        hdma_usart1_rx.Instance = DMA1_Channel5;
        hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
        hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
        hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
        hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
        hdma_usart1_rx.Init.Mode = DMA_NORMAL;
        hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
        if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
        {
            _Error_Handler(__FILE__, __LINE__);
        }

        __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);

        /* USART1_TX Init */
        hdma_usart1_tx.Instance = DMA1_Channel4;
        hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
        hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
        hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
        hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
        hdma_usart1_tx.Init.Mode = DMA_NORMAL;
        hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
        if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
        {
            _Error_Handler(__FILE__, __LINE__);
        }

        __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);

        /* USART1 interrupt Init */
        HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(USART1_IRQn);
        /* USER CODE BEGIN USART1_MspInit 1 */

        /* USER CODE END USART1_MspInit 1 */
    }
}

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{

    if(uartHandle->Instance==USART1)
    {
        /* USER CODE BEGIN USART1_MspDeInit 0 */

        /* USER CODE END USART1_MspDeInit 0 */
        /* Peripheral clock disable */
        __HAL_RCC_USART1_CLK_DISABLE();

        /**USART1 GPIO Configuration
        PA9     ------> USART1_TX
        PA10     ------> USART1_RX
        */
        HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);

        /* USART1 DMA DeInit */
        HAL_DMA_DeInit(uartHandle->hdmarx);
        HAL_DMA_DeInit(uartHandle->hdmatx);

        /* USART1 interrupt Deinit */
        HAL_NVIC_DisableIRQ(USART1_IRQn);
        /* USER CODE BEGIN USART1_MspDeInit 1 */

        /* USER CODE END USART1_MspDeInit 1 */
    }
}

/* USER CODE BEGIN 1 */
/**
  * @brief  Retargets the C library printf function to the USART.
  */
int fputc(int ch,FILE *f)
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
    return ch;
}

/**
  * @brief  This function handles USART1 IDLE interrupt.
  */
void UsartReceive_IDLE(UART_HandleTypeDef *huart)
{
    uint32_t temp;

    if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))
    {
        __HAL_UART_CLEAR_IDLEFLAG(&huart1);
        HAL_UART_DMAStop(&huart1);
        temp = huart1.hdmarx->Instance->CNDTR;
        UsartType.RX_Size =  RX_LEN - temp;
        UsartType.RX_flag=1;
        HAL_UART_Receive_DMA(&huart1,UsartType.RX_pData,RX_LEN);
        UsartType.RX_flag=0;	// clean flag
//           HAL_UART_Transmit(&huart1, UsartType.RX_pData, UsartType.RX_Size, 0xFFFF);
//						HAL_UART_Transmit_DMA(&huart1, UsartType.RX_pData, UsartType.RX_Size);
        if((UsartType.RX_pData[0]==0x5A)&&(UsartType.RX_pData[1]==0xA5))
        {
            if(UsartType.RX_pData[2]==(UsartType.RX_Size-3))
            {
                switch(UsartType.RX_pData[3])
                {
                case 0xF0:
                    if(UsartType.RX_pData[UsartType.RX_Size-1]==myGetXor(UsartType.RX_pData))
                    {
                        temp=(UsartType.RX_pData[4]<<24)+(UsartType.RX_pData[5]<<16)+(UsartType.RX_pData[6]<<8)+UsartType.RX_pData[7];
                        FLASH_If_Init();
                        FLASH_If_Erase(APPTEMP_ADDRESS,APPTEMP_END_ADDRESS);

                        aTxBuffer[0]=0x5A;
                        aTxBuffer[1]=0xA5;
                        aTxBuffer[2]=0x03;
                        aTxBuffer[3]=0xF0;
                        aTxBuffer[4]=0x01;
                        aTxBuffer[5]=aTxBuffer[3]^aTxBuffer[4];
                        HAL_UART_Transmit_DMA(&huart1, (uint8_t *)aTxBuffer, 6);
                    }
                    break;
                case 0xF1:
                    if(UsartType.RX_pData[UsartType.RX_Size-1]==myGetXor(UsartType.RX_pData))
                    {
                        temp=UsartType.RX_pData[7];
											__disable_irq();
                        FLASH_If_Write(APPTEMP_ADDRESS+temp*248,APPTEMP_ADDRESS+temp*248+248,(uint32_t *)UsartType.RX_pData,8,62);
											__enable_irq();
                        aTxBuffer[0]=0x5A;
                        aTxBuffer[1]=0xA5;
                        aTxBuffer[2]=0x03;
                        aTxBuffer[3]=0xF1;
                        aTxBuffer[4]=0x01;
                        aTxBuffer[5]=aTxBuffer[3]^aTxBuffer[4];
                        HAL_UART_Transmit_DMA(&huart1, (uint8_t *)aTxBuffer, 6);
                    }
                    break;
                case 0xF2:
                    if(UsartType.RX_pData[UsartType.RX_Size-1]==myGetXor(UsartType.RX_pData))
                    {
                        temp=(UsartType.RX_pData[4]<<24)+(UsartType.RX_pData[5]<<16)+(UsartType.RX_pData[6]<<8)+UsartType.RX_pData[7];

                        FLASH_If_Erase(PARAMETER_ADDRESS,PARAMETER_END_ADDRESS);
                        FLASH_If_Write(PARAMETER_ADDRESS,PARAMETER_END_ADDRESS,(uint32_t *)UsartType.RX_pData,4,1);

                        aTxBuffer[0]=0x5A;
                        aTxBuffer[1]=0xA5;
                        aTxBuffer[2]=0x03;
                        aTxBuffer[3]=0xF2;
                        aTxBuffer[4]=0x01;
                        aTxBuffer[5]=aTxBuffer[3]^aTxBuffer[4];
                        HAL_UART_Transmit_DMA(&huart1, (uint8_t *)aTxBuffer, 6);
                        q=STMFLASH_ReadWord(PARAMETER_ADDRESS);
                        w=STMFLASH_ReadWord(PARAMETER_ADDRESS+4);
//                        h=q<<16;
//                        p_size=(q<<16)+w;
                    }
										__NOP();
									
                    break;
										case 0xF3:
                    if(UsartType.RX_pData[UsartType.RX_Size-1]==myGetXor(UsartType.RX_pData))
                    {
                       
                        aTxBuffer[0]=0x5A;
                        aTxBuffer[1]=0xA5;
                        aTxBuffer[2]=0x03;
                        aTxBuffer[3]=0xF3;
                        aTxBuffer[4]=0x01;
                        aTxBuffer[5]=aTxBuffer[3]^aTxBuffer[4];
                        HAL_UART_Transmit_DMA(&huart1, (uint8_t *)aTxBuffer, 6);
                        
                                       }
										__NOP();
																		resetFlag=1;
										
                    break;
                default:
                    break;
                }
            }

        }
    }
}
uint8_t myGetXor(uint8_t *p)

{
    uint8_t temp=0;
    for(uint16_t i=0; i<p[2]-1; i++)
    {
        temp=temp^p[i+3];
    }
    return temp;
}
/* USER CODE END 1 */

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
